package jp.shts.ohos.storiesprogressview;

import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorValue;
import ohos.agp.colors.RgbColor;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.components.LayoutScatter;
import ohos.agp.components.StackLayout;
import ohos.agp.components.element.Element;
import ohos.agp.components.element.ShapeElement;
import ohos.app.Context;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;


public class PausableProgressBar extends StackLayout {
    /***
     * progress満了タイマーのデフォルト時間
     */
    private static final int DEFAULT_PROGRESS_DURATION = 2000;
    private static HiLogLabel TAG = new HiLogLabel(HiLog.LOG_APP, 0, "PausableProgressBar");
    private Context context;
    private Component backProgressView;
    private Component frontProgressView;
    private Component maxProgressView;

    private AnimatorValue animation;
    private long duration = DEFAULT_PROGRESS_DURATION;
    private Callback callback;
    private int progressWidth = 0;

    interface Callback {
        void onStartProgress();

        void onFinishProgress();
    }

    public PausableProgressBar(Context context) {
        this(context, null);
    }

    public PausableProgressBar(Context context, AttrSet attrs) {
        this(context, attrs, "");
    }

    public PausableProgressBar(Context context, AttrSet attrs, String styleName) {
        super(context, attrs, styleName);
        this.context = context;
        LayoutScatter.getInstance(context).parse(ResourceTable.Layout_pausable_progress, this, true);
        backProgressView = findComponentById(ResourceTable.Id_back_progress);
        frontProgressView = findComponentById(ResourceTable.Id_front_progress);
        maxProgressView = findComponentById(ResourceTable.Id_max_progress); // work around
        setBindStateChangedListener(new BindStateChangedListener() {
            @Override
            public void onComponentBoundToWindow(Component component) {
                progressWidth = backProgressView.getEstimatedWidth();
                removeBindStateChangedListener(this);
            }

            @Override
            public void onComponentUnboundFromWindow(Component component) {

            }
        });
    }

    public void setDuration(long duration) {
        this.duration = duration;
    }

    public void setCallback(Callback callback) {
        this.callback = callback;
    }

    void setMax() {
        finishProgress(true);
    }

    void setMin() {
        finishProgress(false);
    }

    void setMinWithoutCallback() {
        maxProgressView.setBackground(getColorDrawable(context, ResourceTable.Color_progress_secondary));

        maxProgressView.setVisibility(VISIBLE);
        if (animation != null) {
            animation.setStateChangedListener(null);
            animation.cancel();
        }
    }

    void setMaxWithoutCallback() {
        maxProgressView.setBackground(getColorDrawable(context, ResourceTable.Color_progress_max_active));

        maxProgressView.setVisibility(VISIBLE);
        if (animation != null) {
            animation.setStateChangedListener(null);
            animation.cancel();
        }
    }

    private void finishProgress(boolean isMax) {
        if (isMax) {
            maxProgressView.setBackground(getColorDrawable(context, ResourceTable.Color_progress_max_active));
        }

        maxProgressView.setVisibility(isMax ? VISIBLE : HIDE);
        if (animation != null) {
            animation.setStateChangedListener(null);
            animation.cancel();
            if (callback != null) {
                callback.onFinishProgress();
            }
        }
    }

    public void startProgress() {
        maxProgressView.setVisibility(HIDE);
        animation = new AnimatorValue();
        animation.setDuration(duration);
        animation.setCurveType(AnimatorValue.CurveType.LINEAR);
        animation.setStateChangedListener(new Animator.StateChangedListener() {
            @Override
            public void onStart(Animator animator) {
                frontProgressView.setVisibility(VISIBLE);
                if (callback != null) {
                    callback.onStartProgress();
                }
            }

            @Override
            public void onStop(Animator animator) {
            }

            @Override
            public void onCancel(Animator animator) {
            }

            @Override
            public void onEnd(Animator animator) {
                if (callback != null) {
                    callback.onFinishProgress();
                }
            }

            @Override
            public void onPause(Animator animator) {
            }

            @Override
            public void onResume(Animator animator) {
            }
        });
        animation.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
            @Override
            public void onUpdate(AnimatorValue animatorValue, float value) {
                frontProgressView.setWidth((int) (progressWidth * value));
            }
        });
        animation.start();
    }

    public void pauseProgress() {
        if (animation != null) {
            animation.pause();
        }
    }

    public void resumeProgress() {
        if (animation != null) {
            animation.resume();
        }
    }

    void clear() {
        if (animation != null) {
            animation.setStateChangedListener(null);
            animation.cancel();
            animation = null;
        }
    }

    void reset() {
        if (animation != null) {
            animation.cancel();
        }
    }


    /**
     * 通过颜色id 获取elemet对象
     *
     * @param context 上下文
     * @param res 资源文件
     * @return Element
     */
    public static Element getColorDrawable(Context context, int res) {
        int color = getColor(context, res);
        ShapeElement shapeElement = new ShapeElement();
        shapeElement.setRgbColor(RgbColor.fromArgbInt(color));
        return shapeElement;
    }

    /**
     * 通过颜色id
     *
     * @param context 上下文
     * @param res 资源文件
     * @return int
     */
    public static int getColor(Context context, int res) {
        int result = 0;
        try {
            result = context.getResourceManager().getElement(res).getColor();
        } catch (Exception e) {
            HiLog.info(TAG, "getColor exception", e.getMessage());
        }
        return result;
    }

}
